package com.lanyam.travel.base.interceptor;

import com.lanyam.travel.base.aspect.BaseElinkcareController;
import com.lanyam.travel.base.entity.User;
import com.lanyam.travel.base.utils.JSONResult;
import com.lanyam.travel.base.utils.JsonUtils;
import com.lanyam.travel.base.utils.MD5Utils;
import com.lanyam.travel.base.utils.RedisUtil;

import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author KingTang
 * @date   2019/12/20
 */
@Component(value = "CorsInterceptor")
public class CorsInterceptor extends BaseElinkcareController implements HandlerInterceptor {
	
	@Resource
	private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        allowSosoApi(httpServletResponse);
        if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())){
            httpServletResponse.setStatus(HttpStatus.OK.value());
            return false;
        }
        printBeforeLog4j(httpServletRequest, o);
//        boolean hadLogin = doLoginInterceptor(httpServletRequest,httpServletResponse);
//        return hadLogin;
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        printAfterLog4j(httpServletRequest, o,modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        //do nothing
    }

    private void printBeforeLog4j(HttpServletRequest request, Object handler) throws  Exception{
        // 所有请求第一个进入的方法
        String reqURL = request.getRequestURL().toString();
        String ip = request.getRemoteHost ();
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (handler instanceof HandlerMethod) {
            StringBuilder sb = new StringBuilder(1000);
            sb.append("-------------------------------------------------\n");
            HandlerMethod h = (HandlerMethod) handler;
            //Controller 的包名
            sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n");
            //方法名称
            sb.append("Method    : ").append(h.getMethod().getName()).append("\n");
            //请求方式  post\put\get 等等
            sb.append("RequestMethod    : ").append(request.getMethod()).append("\n");
            //所有的请求参数
            Map returnMap = new HashMap();
            Iterator entries = parameterMap.entrySet().iterator();
            Map.Entry entry;
            String name = "";
            String value = "";
            while (entries.hasNext()) {
                entry = (Map.Entry) entries.next();
                name = (String) entry.getKey();
                Object valueObj = entry.getValue();
                if(null == valueObj){
                    value = "";
                }else if(valueObj instanceof String[]){
                    String[] values = (String[])valueObj;
                    for(int i=0;i<values.length;i++){
                        value = values[i] + ",";
                    }
                    value = value.substring(0, value.length()-1);
                }else{
                    value = valueObj.toString();
                }
                returnMap.put(name, value);
            }
            sb.append("Params    : ").append(returnMap.entrySet().toString()).append("\n");
            //部分请求链接
            sb.append("URI       : ").append(request.getRequestURI()).append("\n");
            //完整的请求链接
            sb.append("AllURI    : ").append(reqURL).append("\n");
            //请求方的 ip地址
            sb.append("request IP: ").append(ip).append("\n");
            System.out.println(sb.toString());

        }

    }

    private void printAfterLog4j(HttpServletRequest request, Object handler, ModelAndView modelAndView){

        String viewName=null,view=null;
        if(modelAndView != null){
            viewName = modelAndView.getViewName();
            view = modelAndView.toString();
        }
        if (handler instanceof HandlerMethod) {
            StringBuilder sb = new StringBuilder(1000);
            sb.append("----------------------------------------------\n");
            HandlerMethod h = (HandlerMethod) handler;
            //Controller 的包名
            sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n");
            //方法名称
            sb.append("Method    : ").append(h.getMethod().getName()).append("\n");
            //请求方式  post\put\get 等等
            sb.append("RequestMethod    : ").append(request.getMethod()).append("\n");
            //视图名称
            sb.append("viewName: ").append(viewName).append("\n");
            //返回有关此模型和视图的信息。
            sb.append("Params   : ").append(view).append("\n");
            System.out.println(sb.toString());

        }
    }


    private void allowSosoApi(HttpServletResponse httpServletResponse) {
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
        httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
        httpServletResponse.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, Token, Authorization");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");


    }
    /**
     * 登陆拦截器，未获取到登陆信息，返回
     * @param request
     * @param response
     * @return
     * @throws UnsupportedEncodingException
     * @throws IOException
     */
    public boolean doLoginInterceptor(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException, IOException
    {
    	//TODO 确少过滤访问
    	
    	String token = request.getHeader("Authorization");
		if (StringUtils.isEmpty(token)) {
			returnErrorResponse(response,JSONResult.errorTokenMsg("未获取到登陆信息，请登录..."));
			return false;
		} else {
			String originToken = MD5Utils.decodeBase64String(token);
			User user = (User) redisUtil.get(originToken);
			if(null == user)
			{
				returnErrorResponse(response, JSONResult.errorTokenMsg("登陆已过期，请重新登陆..."));
				return false;
			}
			else
			{
				redisUtil.expire(originToken, 2*60*60);
			}
		}
    	return true;
    }
    public void returnErrorResponse(HttpServletResponse response, JSONResult result) 
			throws IOException, UnsupportedEncodingException {
		OutputStream out=null;
		try{
		    response.setCharacterEncoding("utf-8");
		    response.setContentType("text/json");
		    out = response.getOutputStream();
		    out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
		    out.flush();
		} finally{
		    if(out!=null){
		        out.close();
		    }
		}
	}
}
